Elasticsearch-99-Java API 常用的几种查询与组合查询

常用的几种查询

准备数据

添加一条数据进去,供测试

1
2
3
4
5
6
7
PUT /car_shop/cars/5
{
"brand": "华晨宝马",
"name": "宝马318",
"price": 270000,
"produce_date": "2017-01-20"
}

全文检索

需求: 全文查询 “宝马”, 一次从brand中搜索,一次从brand和name中搜索

1
2
3
4
5
6
7
8
9
10
11
@Test
public void matchQuery(){
SearchResponse response = client.prepareSearch("car_shop")
.setTypes("cars")
.setQuery(QueryBuilders.matchQuery("brand", "宝马"))
.get();

for (SearchHit hit : response.getHits().getHits()) {
log.info("hit:{}", hit.getSourceAsString());
}
}

console:

1
2
3
4
5
6
7
8
2019-01-23 15:30:18.072 [main] INFO  com.demo.elasticsearch.CarShopTests - hit:{
"brand": "华晨宝马",
"name": "宝马318",
"price": 270000,
"produce_date": "2017-01-20"
}

2019-01-23 15:30:18.073 [main] INFO com.demo.elasticsearch.CarShopTests - hit:{"brand":"宝马","name":"宝马320","price":310000,"produce_date":"2018-01-01"}

第二次,从多个field中查询数据

1
2
3
4
5
6
7
8
9
10
11
@Test
public void multiMatchQuery(){
SearchResponse response = client.prepareSearch("car_shop")
.setTypes("cars")
.setQuery(QueryBuilders.multiMatchQuery("宝马", "brand", "name"))
.get();

for (SearchHit hit : response.getHits().getHits()) {
log.info("hit:{}", hit.getSourceAsString());
}
}

console:

1
2
3
4
5
6
7
8
2019-01-23 15:32:40.852 [main] INFO  com.demo.elasticsearch.CarShopTests - hit:{
"brand": "华晨宝马",
"name": "宝马318",
"price": 270000,
"produce_date": "2017-01-20"
}

2019-01-23 15:32:40.853 [main] INFO com.demo.elasticsearch.CarShopTests - hit:{"brand":"宝马","name":"宝马320","price":310000,"produce_date":"2018-01-01"}

精准查询

精确搜索,就是termQuery
需求: 查询名称是宝马320的数据

1
2
3
4
5
6
7
8
9
10
11
@Test
public void termQuery(){
SearchResponse response = client.prepareSearch("car_shop")
.setTypes("cars")
.setQuery(QueryBuilders.termQuery("name.raw", "宝马320"))
.get();

for (SearchHit hit : response.getHits().getHits()) {
log.info("hit:{}", hit.getSourceAsString());
}
}

console:

1
2019-01-23 15:38:13.984 [main] INFO  com.demo.elasticsearch.CarShopTests - hit:{"brand":"宝马","name":"宝马320","price":310000,"produce_date":"2018-01-01"}

前缀搜索

需求:搜索name是宝开头的数据

1
2
3
4
5
6
7
8
9
10
11
@Test
public void prefixQuery(){
SearchResponse response = client.prepareSearch("car_shop")
.setTypes("cars")
.setQuery(QueryBuilders.prefixQuery("name", "宝"))
.get();

for (SearchHit hit : response.getHits().getHits()) {
log.info("hit:{}", hit.getSourceAsString());
}
}

console:

1
2
3
4
5
6
7
8
2019-01-23 15:47:10.956 [main] INFO  com.demo.elasticsearch.CarShopTests - hit:{
"brand": "华晨宝马",
"name": "宝马318",
"price": 270000,
"produce_date": "2017-01-20"
}

2019-01-23 15:47:10.956 [main] INFO com.demo.elasticsearch.CarShopTests - hit:{"brand":"宝马","name":"宝马320","price":310000,"produce_date":"2018-01-01"}

组合查询

需求:

  • 查询brand必须包含宝马
  • name必须不是宝马318
  • produce_date可以是2017-01-01~2017-01-31之内
  • 过滤出价格是28000-35000的数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Test
public void boolQuery(){
// 组装查询条件
QueryBuilder queryBuilder = QueryBuilders.boolQuery()
.must(QueryBuilders.matchQuery("brand", "宝马"))
.mustNot(QueryBuilders.termQuery("name.raw", "宝马318"))
.should(QueryBuilders.rangeQuery("produce_date").gte("2017-01-01").lte("2017-01-31"))
.filter(QueryBuilders.rangeQuery("price").gte(280000).lte(350000));

// 然后调用搜索接口
SearchResponse response = client.prepareSearch("car_shop")
.setTypes("cars")
.setQuery(queryBuilder)
.get();

// 输出
for (SearchHit hit : response.getHits().getHits()) {
log.info("hit:{}", hit.getSourceAsString());
}
}

console:

1
2019-01-23 16:01:17.074 [main] INFO  com.demo.elasticsearch.CarShopTests - hit:{"brand":"宝马","name":"宝马320","price":310000,"produce_date":"2018-01-01"}